﻿using System;
using System.Data;
using System.Text;
using System.Collections;
using System.IO;
using System.Runtime.InteropServices;

namespace VNPT.DoiSoat
{
    public static class FoxUltil
    {
        //Đếm nhanh số lượng mẫu tin trong file dbf
        public static int CountAllRecord(string path_DbfFile)
        {
            int count = 0;
            using (var br= new BinaryReader(File.OpenRead(path_DbfFile)))
            {
                byte[] buffer = br.ReadBytes(Marshal.SizeOf(typeof(Dbf.DBFHeader)));
                GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                Dbf.DBFHeader header = (Dbf.DBFHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Dbf.DBFHeader));
                return header.numRecords;
            }
            
        }

        public static DataTable GetDataField(string path_DbfFile, out ArrayList Fields)
        {
            StringBuilder strType = new StringBuilder();
            BinaryReader br;
            DataTable Dt = new DataTable();
            Dt.Columns.Add("Field", Type.GetType("System.String"));
            Dt.Columns.Add("Type", Type.GetType("System.String"));

            br = new BinaryReader(File.OpenRead(path_DbfFile));
            byte[] buffer = br.ReadBytes(Marshal.SizeOf(typeof(Dbf.DBFHeader)));

            GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            Dbf.DBFHeader header = (Dbf.DBFHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Dbf.DBFHeader));
            var t= header.numRecords;
            handle.Free();

            ArrayList _fields = new ArrayList();
            while ((13 != br.PeekChar()))
            {
                buffer = br.ReadBytes(Marshal.SizeOf(typeof(Dbf.FieldDescriptor)));
                handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                var tem_ = (Dbf.FieldDescriptor)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Dbf.FieldDescriptor));
                //if (tem_.FieldName != "_NullFlags")
                {
                    _fields.Add(tem_);
                }
               // _fields.Add((Dbf.FieldDescriptor)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Dbf.FieldDescriptor)));
                handle.Free();
            }
            
            Fields = new ArrayList(_fields.Count);
            Fields.AddRange(_fields);

            foreach (Dbf.FieldDescriptor field in _fields)
            {
                switch (field.FieldType)
                {
                    case 'C':
                        strType = new StringBuilder("Character(" + field.FieldLen.ToString() + ")");
                        break;
                    case 'N':
                        strType = new StringBuilder("Numeric(" + field.FieldLen.ToString());
                        if (field.Count > 0)
                        {
                            strType.Append(", " + field.Count.ToString() + ")");
                        }
                        else
                        {
                            strType.Append(")");
                        }
                        break;
                    case 'D':
                        strType = new StringBuilder("Date");
                        break;
                }

                DataRow dr = Dt.NewRow();
                dr["Field"] = field.FieldName;
                dr["Type"] = strType.ToString();

                Dt.Rows.Add(dr);
            }
            br.Close();

            return Dt;
        }
    }
}
